package ru.pb.auth.network;

import java.net.InetAddress;
import java.net.InetSocketAddress;

import ru.pb.auth.configs.AuthNetworkConfig;
import ru.pb.auth.network.clients.AuthClient;
import ru.pb.auth.network.clients.GameServerClient;
import ru.pb.auth.network.engine.AuthClientFactory;
import ru.pb.auth.network.engine.GameClientFactory;
import ru.pb.auth.network.engine.auth.AuthClientPacketListenerHandler;
import ru.pb.auth.network.engine.game.GameServerPacketListenerHandler;
import ru.pb.auth.network.protokol.AuthProtocol;
import ru.pb.auth.network.protokol.GameProtocol;
import ru.pb.global.network.engine.NioAcceptor;
import ru.pb.global.network.engine.core.HelperAdapter;
import ru.pb.global.utils.ExitCode;

public class ANetworkEngine
{
	private static ANetworkEngine _instance;

	private NioAcceptor<AuthClient> _authClientListener;
	private NioAcceptor<GameServerClient> _gameClientListener;

	private static final String auth = "Открыт порт для подключения Игровых клиентов: ";
	private static final String game = "Открыт порт для подключения Игровых серверов: ";

	public static ANetworkEngine getInstance()
	{
		if(_instance == null)
			_instance = new ANetworkEngine();
		return _instance;
	}

	ANetworkEngine()
	{
		try
		{
			InetSocketAddress address;

			if(AuthNetworkConfig.AUTH_SERVER_LISTENER_HOST.equals("*"))
			{
				address = new InetSocketAddress(AuthNetworkConfig.AUTH_SERVER_LISTENER_PORT);
			}
			else
			{
				address = new InetSocketAddress(InetAddress.getByName(AuthNetworkConfig.AUTH_SERVER_LISTENER_HOST), AuthNetworkConfig.AUTH_SERVER_LISTENER_PORT);
			}

			AuthClientFactory gcl = new AuthClientFactory();
			AuthClientPacketListenerHandler gp = new AuthClientPacketListenerHandler();
			HelperAdapter<AuthClient> adapter = new HelperAdapter<AuthClient>(gcl, gcl, gp);
			_authClientListener = new NioAcceptor<AuthClient>(adapter, address, new AuthProtocol(), 1);
			_authClientListener.bind(auth);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(ExitCode.CODE_ERROR.getId());
		}

		try
		{
			InetSocketAddress address;

			if(AuthNetworkConfig.GAME_SERVER_LISTENER_HOST.equals("*"))
			{
				address = new InetSocketAddress(AuthNetworkConfig.GAME_SERVER_LISTENER_PORT);
			}
			else
			{
				address = new InetSocketAddress(InetAddress.getByName(AuthNetworkConfig.GAME_SERVER_LISTENER_HOST), AuthNetworkConfig.GAME_SERVER_LISTENER_PORT);
			}

			GameClientFactory gcl = new GameClientFactory();
			GameServerPacketListenerHandler gp = new GameServerPacketListenerHandler();
			HelperAdapter<GameServerClient> adapter = new HelperAdapter<GameServerClient>(gcl, gcl, gp);
			_gameClientListener = new NioAcceptor<GameServerClient>(adapter, address, new GameProtocol(), 1);
			_gameClientListener.bind(game);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(ExitCode.CODE_ERROR.getId());
		}
	}

	public void unbind()
	{
		_gameClientListener.shutdown();
		_authClientListener.shutdown();
	}
}